package com.webex.ta.hydra.gui;

import com.webex.ta.hydra.core.*;
import com.webex.ta.hydra.core.engine.HydraContextService;
import com.webex.ta.hydra.core.engine.HydraThread;
import com.webex.ta.hydra.core.engine.HydraVariable;
import com.webex.ta.hydra.gui.action.ActionNames;
import com.webex.ta.hydra.gui.action.ActionRouter;
import com.webex.ta.hydra.gui.debug.ResultPane;
import com.webex.ta.hydra.gui.debug.VariablesPane;
import com.webex.ta.hydra.gui.debug.DebugContext;
import com.webex.ta.hydra.gui.menu.HydraMenuBar;
import com.webex.ta.hydra.gui.menu.HydraToolBar;
import com.webex.ta.hydra.gui.util.ThreeSplitPane;
import com.webex.ta.hydra.gui.wm.HydraRootPane;
import com.webex.ta.hydra.gui.wm.ToolWindowIds;
import com.webex.ta.hydra.gui.wm.ToolWindowManager;
import com.webex.ta.hydra.gui.wm.ToolWindowPane;
import com.webex.ta.hydra.gui.project.HydraProjectSuite;
import com.webex.ta.hydra.gui.project.ProjectTabbedPane;
import com.webex.ta.hydra.gui.table.HydraTable;
import com.webex.ta.hydra.util.HydraUtils;
import com.webex.ta.hydra.util.HydraVersion;

import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-8-27
 * Time: 9:27:41
 */
public class HydraIdeFrame extends JFrame implements TestListener {

    public static final String DEFAULT_TITLE =
    	"Hydra " + HydraVersion.getVERSION() + "";

    private HydraMenuBar menuBar;
    private HydraToolBar toolBar;
    private ProjectTabbedPane editorContainer;

    private Command debugCommand;
    private JComponent debugPane;
    private ResultPane resultPane;
    private VariablesPane varsPane;
    private HydraRootPane rootPane;


    public HydraIdeFrame() {
        super();
        this.setIconImage(HydraUtils.getImage("hydra.jpg").getImage());
        GuiPackage.getInstance().setIdeFrame(this);

        rootPane = new HydraRootPane();
        setRootPane(rootPane);

        menuBar = new HydraMenuBar();
        toolBar = new HydraToolBar();
        menuBar.testStop();
        toolBar.testStop();
        setJMenuBar(menuBar);
        rootPane.setToolBar(toolBar);

        GuiPackage.getInstance().setToolBar(toolBar);
        GuiPackage.getInstance().setMenu(menuBar);
        ToolWindowPane toolWindowPane = new ToolWindowPane(this, ToolWindowManager.getInstance());
        toolWindowPane.setDocumentComponent(createMainPanel());
        rootPane.setToolWindowPane(toolWindowPane);

        addWindowListener(new MainFrameWindowListener());
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

        debugPane = createDebugPanel();
        createResultPanel();

        ToolWindowManager.getInstance().registerToolWindow(
                ToolWindowIds.RESULT, resultPane, SwingConstants.BOTTOM, "Test Result", HydraUtils.getImage("results.gif"));
        ToolWindowManager.getInstance().registerToolWindow(
                ToolWindowIds.DEBUG, debugPane, SwingConstants.BOTTOM, "Debug", HydraUtils.getImage("debug_exc.gif"));
    }

    private JComponent createMainPanel() {
        ThreeSplitPane split = new ThreeSplitPane();
        split.setInnerComponent(createDocumentPanel());
        return split;
    }

    private JComponent createDocumentPanel() {
        editorContainer = new ProjectTabbedPane();
        editorContainer.setOpaque(true);
        return editorContainer;
    }

    public void addProject(HydraProjectSuite project) {
        editorContainer.addProject(project);
        installListSelectionListener(project.getTable());
        project.getTable().adjustColumnCount();
    }

    public void removeProject(HydraProjectSuite project) {
        editorContainer.removeProject(project);
    }

    public void activateProject(HydraProjectSuite project) {
        editorContainer.activateProject(project);
    }

    public void updateProjectName(HydraProjectSuite project) {
        editorContainer.updateProjectName(project);
    }

    public Collection<HydraProjectSuite> getProjects() {
        return editorContainer.getProjects();
    }


    public HydraProjectSuite getActiveProject() {
        return editorContainer.getActiveProject();
    }

    private JComponent createDebugPanel() {
//        ClosableTabbedPane tab = new ClosableTabbedPane(JTabbedPane.BOTTOM, JTabbedPane.SCROLL_TAB_LAYOUT);
        JTabbedPane tab = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
//        tab.addTab("Results", HydraUtils.getImage("results.gif"), createResultPanel());
        tab.addTab("Variables", HydraUtils.getImage("variable_tab.gif"), createVariablesPanel());
        tab.addTab("Context", HydraUtils.getImage("context.gif"), new JPanel());
        return tab;
    }

    private Component createResultPanel() {
        resultPane = new ResultPane();
        return resultPane;
    }

    private Component createVariablesPanel() {
        varsPane = new VariablesPane();
        return varsPane;
    }

    private JComponent createListPanel() {
        return new JPanel();
    }


    public ResultPane getResultPane() {
        return resultPane;
    }

    public void installListSelectionListener(HydraTable table) {
        table.getSelectionModel().addListSelectionListener(new MyListSelectionListener(table));
    }


    public void beforeTestStart() {
        resultPane.clear();
//        if (currentPane != null) {
//            currentPane.getTable().lock();
//        }

    }

    public void testStarted(HydraThread source) {
        menuBar.testStart();
        toolBar.testStart();
        ToolWindowManager.getInstance().showToolWindow(ToolWindowIds.RESULT);
    }

    public void testPaused(HydraThread source) {
        if (debugCommand != null) {
            debugCommand.clearDebugInfo();
        }
        debugCommand = HydraContextService.getContext().getCurrentCommand();
        debugCommand.setInDebug(true);

        HydraProjectSuite project = DebugContext.getInstance().getDebugProject();
        project.getEditorPane().getTable().makeVisible(debugCommand);
        project.getModel().fireTableDataChanged();

        menuBar.testPaused();
        toolBar.testPaused();
        varsPane.setVars(source.getThreadContext().getVariables().getVariableDetails());
    }

    public void testResumed(HydraThread source) {
        menuBar.testStart();
        toolBar.testStart();
    }

    public void testEnded(HydraThread source) {
        if (debugCommand != null) {
            debugCommand.clearDebugInfo();
            DebugContext.getInstance().getDebugProject().getModel().fireTableDataChanged();
        }
        menuBar.testStop();
        toolBar.testStop();
        varsPane.setVars(new HydraVariable[0]);
    }

    public void setExtendedFrameTitle(String fname) {
		// file New operation may set to null, so just return app name
		if (fname == null) {
			setTitle(DEFAULT_TITLE);
			return;
		}

		// allow for windows / chars in filename
		String temp = fname.replace('\\', '/');
		String simpleName = temp.substring(temp.lastIndexOf("/") + 1);
		setTitle(simpleName + " (" + fname + ") - " + DEFAULT_TITLE);
	}

    public void projectFileLoaded(String file) {
        menuBar.projectFileLoaded(file);
    }

    public void clearTestResults() {
        resultPane.clear();
    }


    private static class MainFrameWindowListener extends WindowAdapter {
        @Override
        public void windowClosing(WindowEvent e) {
            ActionRouter.getInstance().actionPerformed(new ActionEvent(this, e.getID(), ActionNames.EXIT));
        }
    }



    private class MyListSelectionListener implements ListSelectionListener {
        private HydraTable table;

        public MyListSelectionListener(HydraTable table) {
            this.table = table;
        }

        public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting())
                    return;

                int idx = ((ListSelectionModel) e.getSource()).getMinSelectionIndex();
                if (idx >= 0) {
                    Command cmd = table.getModel().getCommandAt(idx);
                    resultPane.setInspect(cmd);
                }
        }
    }
}
